#include "TestAI.h"
#include "globalne.h"
#include <algorithm>
baza::baza(IAICallback *callback,TTAICore *Gl, string opis)
{
//	LOGUJ ("\t\t\tKonstruktor bazy. Nadawanie nazwy...  ");
	ileFabryk=0;
	nazwa=opis;
//	LOGUJ ("done\tDawanie globala i cb...");
    cb=callback;
    G=Gl;   	
	oddzialyKons.G=G;
	oddzialyKons.cb=cb;
	projekty.G=G;
	projekty.cb=cb;
//	oddzialyKons.reserve(512);
//	LOGUJ ("done"<<endl<<"\t\t\tPowstala baza o nazwie "<<opis<<"."<<endl);
}

baza::~baza()
{}

bool baza::dodajBaze(baza * doDodania)
{
	LOGUJ ("Dodaje baze o nazwie "<< doDodania->nazwa <<" do bazy o nazwie "<< this->nazwa <<endl);
	this->antyAt|=doDodania->antyAt;
	this->ileFabryk+=doDodania->ileFabryk;
	for(int i=0; i<doDodania->budynki.size(); ++i)
	{
		this->budynki.push_back(doDodania->budynki[i]);
	}
	this->nazwa=this->nazwa+"+"+doDodania->nazwa;
	for(int i=0; i<doDodania->sektory.size(); ++i)
	{
		this->sektory.push_back(doDodania->sektory[i]);
	}
	this->priorytet+=doDodania->priorytet;
	for(int i=0; i<doDodania->oddzialyKons.size(); ++i)
	{
		this->oddzialyKons.push_back(doDodania->oddzialyKons[i]);
	}
	return true;
}
bool baza::dodajSektor (int ktory)
{
	LOGUJ ("\t\t\tDodaje sektor "<< ktory <<" do bazy o nazwie "<<nazwa<<"."<<endl);
	sektory.push_back(ktory);
	G->M->sek[ktory].ktora=this;
	return true;
}
int baza::losowySektor()
{
	LOGUJ ("Losuje sektor z bazy "<< nazwa <<". Wybrano:");
	int ret=rand()%sektory.size();
	LOGUJ (sektory[ret]<<endl);
	return sektory[ret];
}
bool baza::stworzOddzialKons(int id, jednostka * pierwszy)
{
	LOGUJ ("Tworze oddzial konstrukcyjny. Pierwszym czlonkiem i liderem jest " << pierwszy->info->name <<endl);
	/*budowlancy * nowi=new budowlancy ;
	nowi->cb=cb;
	nowi->G=G;
	nowi->przyjmijcie(id,pierwszy);
	nowi->lider=id;
	nowi->poziom=pierwszy->poziomBuduje;
	nowi->mojaBaza=this;
	nowi->typ=1;
	nowi->czlonkowie.G=G;
	nowi->czlonkowie.cb=cb;
	budowlancy * now=new budowlancy;*/
	budowlancy nowi;
	nowi.cb=cb;
	nowi.G=G;
	nowi.czlonkowie.glowa.nast=0;
	nowi.czlonkowie.glowa.zawart=0;
	nowi.czlonkowie.G=G;
	nowi.czlonkowie.cb=cb;
	nowi.przyjmijcie(id,pierwszy);
	nowi.lider=id;
	nowi.poziom=pierwszy->poziomBuduje;
	nowi.mojaBaza=this;
	nowi.typ=1;
	oddzialyKons+=nowi;
	LOGUJ ("Ma on adres w pamieci: "<<(oddzialyKons.glowa.nast->zawart)<<endl);
	pierwszy->mojOddzial=oddzialyKons(0);
	LOGUJ ("pierwszy->mojoddzial="<<pierwszy->mojOddzial<<endl);
	return true;
}
projekt baza::najblizszyProjekt (budowlancy * bb)
{	
	int najb;
	float3 lid=(cb->GetUnitPos(bb->lider));
	float odl;
	bool j=true;
	int ile=projekty.size();
	if (!projekty.size())
	{
		projekt n(G);
		n.pos=NIGDZIE;
		return n;
	}
	else
	{

		for (int i=0; i<ile; i++)
		{
			if(j)
			{
				odl=G->M->odlPunktow(lid,projekty[i].pos);
				j=false;
				najb=i;
				continue;
			}
			else if (G->M->odlPunktow(lid,projekty[i].pos)<odl)
			{
				odl=G->M->odlPunktow(lid,projekty[i].pos);
				najb=i;
			}

		}
	}
	return projekty[najb];
}
void baza::nowyProjekt(int uid, jednostka * jj) 
{
	const UnitDef* jednostka=cb->GetUnitDef(uid);
	int ileProj=projekty.size();
	projekt nowy(G);
	nowy.pr=jj;
	nowy.pos=cb->GetUnitPos(uid);
	nowy.liderzy.G=G;
	nowy.liderzy.cb=cb;
	projekty+=nowy;
	LOGUJ ("Stworzylem nowy projekt! Jego dane:"<<endl<<nowy<<endl);
	LOGUJ ("Laczna liczba aktywnych projektow:"<<projekty.size()<<endl);
	piszProj();

	///////////stara czesc funkcji - moze kiedys cos byc z niej potrzebne////////////////
	/*float3 pos=cb->GetUnitPos(uid);	
	float distance=-1;
	int unit=-1;

    for (int i=0;i!=NumProjects;i++) {
		if (distance>G->sa->calcdistance(pos,activeprojects[i].pos)||distance==-1) {
			if (activeprojects[i].beingbuilt&&activeprojects[i].uid==0) {
				distance=G->sa->calcdistance(pos,activeprojects[i].pos);
				unit=i;	
			}
		}
	}
	if (unit==-1) {
      int error=1;return;
	}
	activeprojects[unit].uid=uid;*/

}
void baza::piszProj()
{
	int ileProj=projekty.size();		
	LOGUJ ("Projekty w budowie:"<<endl);
    for (int i=0;i!=ileProj;i++) 
	{
		LOGUJ ("\t"<<i<<". "<<projekty[i]<<endl);
	}
}
void baza::projektSkonczony(int uid, jednostka * jj) 
{
	int ileProj=projekty.size();		
	LOGUJ ("\t\tProjekt zakonczony. ID="<<uid<<"   zakanczanie...");
	piszProj();
    for (int i=0;i!=ileProj;i++) 
	{
		if (projekty[i].pr->mojId==uid) 
		{
			int ile=projekty[i].liderzy.size();
			for (int j=0; j<ile; i++)
			{
				G->M->jednostkaBezrobotna(projekty[i].liderzy[j],cb->GetUnitDef(projekty[i].liderzy[j]));
			}
			projekty.erase(i);
			piszProj();
			LOGUJ ("done!"<<endl);
			break;
		}
	}
}
void baza::projektPrzerwany(int uid, jednostka * jj) 
{
	int ileProj=projekty.size();	
	LOGUJ ("\t\tProjekt przerwany. ID="<<uid<<"   zakanczanie...");
	piszProj();
    for (int i=0;i!=ileProj;i++) 
	{
		if (projekty[i].pr->mojId==uid) 
		{
			int ile=projekty[i].liderzy.size();
			for (int j=0; j<ile; j++)
			{
				G->M->jednostkaBezrobotna(projekty[i].liderzy[j],cb->GetUnitDef(projekty[i].liderzy[j]));
			}
			projekty.erase(i);
			piszProj();
			LOGUJ ("done!"<<endl);
			break;
		}
	}
	
}
std::ostream & operator<<(std::ostream & wy, projekt proj)
{
	wy<<"Zaawansowany projekt: "<<proj.pr->info->name<<endl
		<<"ID: "<<proj.pr->mojId<<endl;
	return wy;
}
